package com.ossjk.core.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;

import org.hyperic.jni.ArchNotSupportedException;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarLoader;

public class OsUtil {

	private static Sigar sigar = null;
	static {
		try {
			initSigar();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 初始化sigar的配置文件
	public static void initSigar() throws IOException {
		SigarLoader loader = new SigarLoader(Sigar.class);
		String lib = "sigar-amd64-winnt.dll";
		try {
			lib = loader.getLibraryName();
		} catch (ArchNotSupportedException e) {
			e.printStackTrace();
		}
		URL url = OsUtil.class.getClassLoader().getResource("sigar/" + lib);
		if (url != null) {
			InputStream is = OsUtil.class.getClassLoader().getResourceAsStream("sigar/" + lib);
			File tempDir = new File("./logs");
			if (!tempDir.exists()) {
				tempDir.mkdirs();
			}
			BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(new File(tempDir, lib), false));
			int lentgh = 0;
			while ((lentgh = is.read()) != -1) {
				os.write(lentgh);
			}
			is.close();
			os.close();
			System.setProperty("org.hyperic.sigar.path", tempDir.getCanonicalPath());

		}
		sigar = new Sigar();
	}
	/**
	 * 获取客户端ip地址
	 * 
	 * @param request
	 * @return
	 */
	public static String getCliectIp(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}

		// 多个路由时，取第一个非unknown的ip
		final String[] arr = ip.split(",");
		for (final String str : arr) {
			if (!"unknown".equalsIgnoreCase(str)) {
				ip = str;
				break;
			}
		}
		return ip;
	}

	public static CpuInfo getCpuInfo() {
		CpuInfo cpuInfo = null;
		try {
			cpuInfo = new CpuInfo();
			org.hyperic.sigar.CpuInfo info = sigar.getCpuInfoList()[0];
			CpuPerc cpuPerc = sigar.getCpuPerc();

			cpuInfo.setCombined(cpuPerc.getCombined());
			cpuInfo.setMhz(info.getMhz());
			cpuInfo.setTotalCores(info.getTotalCores());
			cpuInfo.setModel(info.getModel());
			cpuInfo.setIdle(cpuPerc.getIdle());
		} catch (SigarException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return cpuInfo;
	}

	public static JvmInfo getJvmInfo() {
		JvmInfo jvmInfo = null;
		jvmInfo = new JvmInfo();
		Runtime r = Runtime.getRuntime();
		Properties props = System.getProperties();
		jvmInfo.setMemoryTotal(r.totalMemory());
		jvmInfo.setMemoryFree(r.freeMemory());
		jvmInfo.setMemoryUsed(r.totalMemory() - r.freeMemory());
		jvmInfo.setJavaVersion(props.getProperty("java.version"));
		jvmInfo.setJvmVersion(props.getProperty("java.vm.version"));
		jvmInfo.setSpecVersion(props.getProperty("java.vm.specification.version"));
		jvmInfo.setAvailableProcessors((long) r.availableProcessors());
		return jvmInfo;
	}

	public static OsMemory getOsMemory() {
		OsMemory osMemory = null;
		osMemory = new OsMemory();
		Mem mem;
		try {
			mem = sigar.getMem();
			osMemory.setMemoryTotal(mem.getTotal());
			osMemory.setMemoryFree(mem.getFree());
			osMemory.setMemoryUsed(mem.getUsed());
		} catch (SigarException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return osMemory;
	}

	public static OsInfo getOsInfo() {
		OsInfo osInfo = null;
		osInfo = new OsInfo();
		Properties props = System.getProperties();
		osInfo.setOsName(props.getProperty("os.name"));
		osInfo.setOsArch(props.getProperty("os.arch"));
		osInfo.setJavaVersion(props.getProperty("java.specification.version"));
		return osInfo;
	}

	public static class JvmInfo {
		// jvm内存总量
		private Long memoryTotal;
		// jvm内存使用量
		private Long memoryUsed;
		// jvm内存剩余量
		private Long memoryFree;
		// jvm使用处理器数量
		private Long availableProcessors;
		// jvm规范版本号
		private String specVersion;
		// jvm实现版本号
		private String jvmVersion;
		// java运行环境版本
		private String javaVersion;

		public Long getMemoryTotal() {
			return memoryTotal;
		}

		public void setMemoryTotal(Long memoryTotal) {
			this.memoryTotal = memoryTotal;
		}

		public Long getMemoryUsed() {
			return memoryUsed;
		}

		public void setMemoryUsed(Long memoryUsed) {
			this.memoryUsed = memoryUsed;
		}

		public Long getMemoryFree() {
			return memoryFree;
		}

		public void setMemoryFree(Long memoryFree) {
			this.memoryFree = memoryFree;
		}

		public String getSpecVersion() {
			return specVersion;
		}

		public void setSpecVersion(String specVersion) {
			this.specVersion = specVersion;
		}

		public String getJvmVersion() {
			return jvmVersion;
		}

		public void setJvmVersion(String jvmVersion) {
			this.jvmVersion = jvmVersion;
		}

		public String getJavaVersion() {
			return javaVersion;
		}

		public void setJavaVersion(String javaVersion) {
			this.javaVersion = javaVersion;
		}

		public Long getAvailableProcessors() {
			return availableProcessors;
		}

		public void setAvailableProcessors(Long availableProcessors) {
			this.availableProcessors = availableProcessors;
		}

		@Override
		public String toString() {
			return "JvmInfo [memoryTotal=" + memoryTotal + ", memoryUsed=" + memoryUsed + ", memoryFree=" + memoryFree + ", availableProcessors=" + availableProcessors + ", specVersion=" + specVersion + ", jvmVersion=" + jvmVersion + ", javaVersion=" + javaVersion + ", getMemoryTotal()=" + getMemoryTotal() + ", getMemoryUsed()=" + getMemoryUsed() + ", getMemoryFree()=" + getMemoryFree() + ", getSpecVersion()=" + getSpecVersion() + ", getJvmVersion()=" + getJvmVersion() + ", getJavaVersion()=" + getJavaVersion() + ", getAvailableProcessors()=" + getAvailableProcessors() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
		}

	}

	public static class OsMemory {
		// 系统内存总量
		private Long memoryTotal;
		// 系统内存使用量
		private Long memoryUsed;
		// 系统内存剩余量
		private Long memoryFree;

		public Long getMemoryTotal() {
			return memoryTotal;
		}

		public void setMemoryTotal(Long memoryTotal) {
			this.memoryTotal = memoryTotal;
		}

		public Long getMemoryUsed() {
			return memoryUsed;
		}

		public void setMemoryUsed(Long memoryUsed) {
			this.memoryUsed = memoryUsed;
		}

		public Long getMemoryFree() {
			return memoryFree;
		}

		public void setMemoryFree(Long memoryFree) {
			this.memoryFree = memoryFree;
		}

		@Override
		public String toString() {
			return "OsMemory [memoryTotal=" + memoryTotal + ", memoryUsed=" + memoryUsed + ", memoryFree=" + memoryFree + ", getMemoryTotal()=" + getMemoryTotal() + ", getMemoryUsed()=" + getMemoryUsed() + ", getMemoryFree()=" + getMemoryFree() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
		}

	}

	public static class OsInfo {
		// 操作系统名字
		private String OsName;
		// 操作系统架构
		private String OsArch;
		// java运行版本
		private String JavaVersion;

		public String getOsName() {
			return OsName;
		}

		public void setOsName(String osName) {
			OsName = osName;
		}

		public String getOsArch() {
			return OsArch;
		}

		public void setOsArch(String osArch) {
			OsArch = osArch;
		}

		public String getJavaVersion() {
			return JavaVersion;
		}

		public void setJavaVersion(String javaVersion) {
			JavaVersion = javaVersion;
		}

		@Override
		public String toString() {
			return "OsInfo [OsName=" + OsName + ", OsArch=" + OsArch + ", JavaVersion=" + JavaVersion + ", getOsName()=" + getOsName() + ", getOsArch()=" + getOsArch() + ", getJavaVersion()=" + getJavaVersion() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
		}

	}

	public static class CpuInfo {
		// Cpu型号
		private String model;
		// Cpu主频
		private int mhz;
		// Cpu核心数
		private int totalCores;
		// Cpu总使用率
		private double combined;
		// Cpu总空闲率
		private double idle;

		public double getIdle() {
			return idle;
		}

		public void setIdle(double idle) {
			this.idle = idle;
		}

		public String getModel() {
			return model;
		}

		public void setModel(String model) {
			this.model = model;
		}

		public int getMhz() {
			return mhz;
		}

		public void setMhz(int mhz) {
			this.mhz = mhz;
		}

		public int getTotalCores() {
			return totalCores;
		}

		public void setTotalCores(int totalCores) {
			this.totalCores = totalCores;
		}

		public double getCombined() {
			return combined;
		}

		public void setCombined(double combined) {
			this.combined = combined;
		}

		@Override
		public String toString() {
			return "CpuInfo [model=" + model + ", mhz=" + mhz + ", totalCores=" + totalCores + ", combined=" + combined + ", idle=" + idle + ", getIdle()=" + getIdle() + ", getModel()=" + getModel() + ", getMhz()=" + getMhz() + ", getTotalCores()=" + getTotalCores() + ", getCombined()=" + getCombined() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
		}

	}

	public static void main(String[] args) {
		OsUtil osUtil = new OsUtil();
		osUtil.getCpuInfo();
	}

}
